# -*- coding: utf-8 -*-
"""
DateTime   : 2023/11/30 9:17
Author     : ZhangYafei
Description:
华为交换机增加用户
华为交换机修改密码
"""
import time

import pandas as pd
import paramiko
import socket


class HuaweiSwitch:
    def __init__(self, hostname: str, username: str, password: str):
        self.hostname = hostname
        self.username = username
        self.password = password
        self.__ssh_client = self.build_connect(username=self.username, password=self.password)

    def build_connect(self, username: str, password: str):
        ssh_client = paramiko.SSHClient()
        ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh_client.connect(hostname=self.hostname, username=username, password=password)
        return ssh_client

    def connect_close(self):
        self.__ssh_client.close()

    def __close__(self):
        self.connect_close()

    def login_verify(self, username: str, password: str):
        """
        登录校验
        :param hostname:
        :param username:
        :param password:
        :return:
        """
        ssh_client = paramiko.SSHClient()  # 调用paramiko的SSHClient方法连接网络设备，及本地设备为客户端
        connect_res = {'hostname': self.hostname, 'username': username, 'password': password, 'success': False,
                       'info': None}
        try:
            ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh_client.connect(hostname=self.hostname, username=username,
                               password=password)  # 调用connect()方法，输入连接设备所需的ip，用户名，密码
            ssh_client.close()
            connect_res['success'] = True
            connect_res['info'] = f"连接成功"
        except paramiko.ssh_exception.NoValidConnectionsError:
            connect_res['info'] = '连接失败，用户不存在'
        except paramiko.ssh_exception.AuthenticationException:
            connect_res['info'] = "连接失败，密码错误"
        except socket.error:
            connect_res['info'] = "连接失败，socket.error"
        except Exception as e:
            connect_res['info'] = f"连接失败，{e}"
        return connect_res

    def modify_password(self, username: str, password: str, new_password: str):
        """
        修改密码
        :param ssh_client:
        :param username:
        :param password:
        :param new_password:
        :return:
        """
        print(f'用户：{username}的密码修改中-----------')
        self.__ssh_client = self.__ssh_client.invoke_shell()
        self.__ssh_client.send("sys" + "\n")
        self.__ssh_client.send("aaa" + "\n")
        self.__ssh_client.send(f"local-user {username} password irreversible-cipher {new_password}\n")
        time.sleep(1)
        self.__ssh_client.send(f"{password}\n")
        self.__ssh_client.send("quit\n")
        print("修改完成-----------")
        output = self.__ssh_client.recv(65535).decode()
        print(output)
        res = self.login_verify(username=username, password=new_password)
        return res

    def add_account(self, username: str, password: str):
        """
        修改密码
        :param ssh_client:
        :param username:
        :param password:
        :param new_password:
        :return:
        """
        print(f'用户：{username} 新建中-----------')
        self.__ssh_client = self.__ssh_client.invoke_shell()
        self.__ssh_client.send("sys" + "\n")
        self.__ssh_client.send(f"ssh user {username}" + "\n")
        self.__ssh_client.send(f"ssh user {username} service-type stelnet" + "\n")
        self.__ssh_client.send(f"ssh user {username} authentication-type password" + "\n")
        self.__ssh_client.send("aaa" + "\n")
        self.__ssh_client.send(f"local-user {username} password irreversible-cipher {password}\n")
        self.__ssh_client.send(f"local-user {username} privilege level 15" + "\n")
        self.__ssh_client.send(f"local-user {username} service-type ssh" + "\n")
        self.__ssh_client.send("quit\n")
        print(f"新建用户{username}-{password}完成-----------")
        output = self.__ssh_client.recv(65535).decode()
        print(output)
        res = self.login_verify(username=username, password=password)
        return res


def modify_account():
    # switch_df = pd.read_excel('data/交换机设备账户.xlsx')
    # switch_df.apply(switch_operation_func, axis=1)
    hostname = 'XXXX'
    username = 'XXXX'
    password = 'XXXX'
    new_password = "XXXX"
    try:
        huawei_switch = HuaweiSwitch(hostname=hostname, username=username, password=password)
        res = huawei_switch.modify_password(username=username, password=password, new_password=new_password)
    except paramiko.ssh_exception.AuthenticationException:
        res = {"hostname": hostname, "username": username, "password": password, "info": "连接失败，用户认证失败"}
    except socket.error:
        res = {"hostname": hostname, "username": username, "password": password, "info": "连接失败，socket.error"}
    except Exception as e:
        res = {"hostname": hostname, "username": username, "password": password, "info": f"连接失败，{e}"}
    print(res)


def apply_new_user(row):
    hostname, username, password = row['管理地址'], row['账户'], row['密码']
    new_username, new_password = row['添加账户1'], row['添加账户1密码']
    try:
        huawei_switch = HuaweiSwitch(hostname=hostname, username=username, password=password)
        print(f"{hostname}: {username}-{password} 登录成功")
        res = huawei_switch.add_account(username=new_username, password=new_password)
    except paramiko.ssh_exception.AuthenticationException:
        res = {"hostname": hostname, "username": username, "password": password, "info": "连接失败，用户认证失败"}
    except socket.error:
        res = {"hostname": hostname, "username": username, "password": password, "info": "连接失败，socket.error"}
    except Exception as e:
        res = {"hostname": hostname, "username": username, "password": password, "info": f"连接失败，{e}"}
    print(res)
    return res['info']


def add_new_users():
    switch_df = pd.read_excel('data/交换机设备账户.xlsx', sheet_name='信息中心三层')
    # switch_df = switch_df[switch_df['类型'] == '内网']
    switch_df = switch_df[switch_df['类型'] == '外网']
    switch_df['新建用户结果'] = switch_df.apply(apply_new_user, axis=1)
    switch_df.to_excel('三层信息中心内网交换机外网.xlsx', index=False)


if __name__ == '__main__':
    # modify_account()
    add_new_users()
